package asia.gkc.test.handler;

import asia.gkc.test.protocol.DefaultParser;
import asia.gkc.test.util.ByteBufToBytes;
import asia.gkc.test.util.DataModel;
import io.netty.buffer.ByteBuf;
import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.ChannelInboundHandlerAdapter;
import io.netty.handler.codec.DecoderException;
import io.netty.util.AttributeKey;
import io.netty.util.ReferenceCountUtil;

/**
 * File Name: DataDispatchHandler.java
 * Function:
 *
 * @author jakes.
 * @version 1.0
 * @since 6/26/16 11:37 PM
 */

public class DataDispatchHandler extends ChannelInboundHandlerAdapter {
    final static AttributeKey<String> MAC_ID = AttributeKey.valueOf("MAC_ID");
    private DefaultParser defaultParser = new DefaultParser();
    private HealthData healthData;

    public DataDispatchHandler() {
        this.healthData = HealthData.getInstance();
    }

    @Override
    public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception {
        ByteBuf in = (ByteBuf) msg;
        try {
            while (in.isReadable()) {
                byte[] data = ByteBufToBytes.toBytes(in);
                DataModel dataModel = defaultParser.parseData(data);

                if (dataModel == null) {
                    System.out.println("Unknown data type!");
                    return;
                }

                switch (dataModel.getDataType()) {
                    case DefaultParser.LOGIN_MAC:
                        ctx.channel().attr(MAC_ID).set(dataModel.getData());
                        System.out.println("set mac id: " + dataModel.getData());
                        break;
                    case DefaultParser.DEVICE_STATUS:
                        System.out.println("User left at: " + dataModel.getData());
                        break;
                    default:
                        if (ctx.channel().attr(MAC_ID).get() != null)
                            healthData.notifyObservers(dataModel, dataModel.getDataType());
                }
            }
        } finally {
            ReferenceCountUtil.release(msg);
        }
    }

    @Override
    public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) throws Exception {
        if (! (cause instanceof DecoderException))
            ctx.close();
        System.out.println("Unexpected packet structure!");
    }
}
